﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace CharacterCreation.Controls {
    public class ListBox : ItemsControl {
        #region Templates
        /// <summary>
        /// The CustomItemTemplate property.
        /// </summary>
        public DataTemplate CustomItemTemplate {
            get { return (DataTemplate)GetValue(CustomItemTemplateProperty); }
            set { SetValue(CustomItemTemplateProperty, value); }
        }
        public static readonly DependencyProperty CustomItemTemplateProperty =
            DependencyProperty.Register("CustomItemTemplate", typeof(DataTemplate), typeof(ListBox), null);

        /// <summary>
        /// The SelectedItemTemplate property.
        /// </summary>
        public DataTemplate SelectedItemTemplate {
            get { return (DataTemplate)GetValue(SelectedItemTemplateProperty); }
            set { SetValue(SelectedItemTemplateProperty, value); }
        }
        public static readonly DependencyProperty SelectedItemTemplateProperty =
            DependencyProperty.Register("SelectedItemTemplate", typeof(DataTemplate), typeof(ListBox), null);

        /// <summary>
        /// The HoverItemTemplate property.
        /// </summary>
        public DataTemplate HoverItemTemplate {
            get { return (DataTemplate)GetValue(HoverItemTemplateProperty); }
            set { SetValue(HoverItemTemplateProperty, value); }
        }
        public static readonly DependencyProperty HoverItemTemplateProperty =
            DependencyProperty.Register("HoverItemTemplate", typeof(DataTemplate), typeof(ListBox), null);

        /// <summary>
        /// The HoverItemTemplate property.
        /// </summary>
        public DataTemplate HoverSelectedItemTemplate {
            get { return (DataTemplate)GetValue(HoverSelectedItemTemplateProperty); }
            set { SetValue(HoverSelectedItemTemplateProperty, value); }
        }
        public static readonly DependencyProperty HoverSelectedItemTemplateProperty =
            DependencyProperty.Register("HoverSelectedItemTemplate", typeof(DataTemplate), typeof(ListBox), null);
        #endregion Templates

        #region Selection
        /// <summary>
        /// The SelectedItem property.
        /// </summary>
        public object SelectedItem {
            get { return (object)GetValue(SelectedItemProperty); }
            set {
                if (SelectedItemChangedCommand != null)
                    SelectedItemChangedCommand.Execute(value);
                SetValue(SelectedItemProperty, value);
                
                if (value == null && SelectedListBoxItem != null) {
                    SelectedListBoxItem.IsSelected = false;
                }

            }
        }
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(object), typeof(ListBox), null);

        /// <summary>
        /// The SelectedItemChangedCommand property.
        /// </summary>
        public ICommand SelectedItemChangedCommand {
            get { return (ICommand)GetValue(SelectedItemChangedCommandProperty); }
            set { SetValue(SelectedItemChangedCommandProperty, value); }
        }
        public static readonly DependencyProperty SelectedItemChangedCommandProperty =
            DependencyProperty.Register("SelectedItemChangedCommand", typeof(ICommand), typeof(ListBox), null);

        /// <summary>
        /// The AllowMultiSelect property.
        /// </summary>
        public bool AllowMultiSelect {
            get { return (bool)GetValue(AllowMultiSelectProperty); }
            set { SetValue(AllowMultiSelectProperty, value); }
        }
        public static readonly DependencyProperty AllowMultiSelectProperty =
            DependencyProperty.Register("AllowMultiSelect", typeof(bool), typeof(ListBox), null);

        /// <summary>
        /// The SelectedItems property.
        /// </summary>
        public ObservableCollection<object> SelectedItems {
            get {
                if (GetValue(SelectedItemsProperty) == null) {
                    this.SelectedItems = new ObservableCollection<object>();
                    this.SelectedItems.CollectionChanged += (s, e) => {
                        if (SelectionChangedCommand != null)
                            SelectionChangedCommand.Execute(this.SelectedItems);
                    };
                }
                return (ObservableCollection<object>)GetValue(SelectedItemsProperty);
            }
            set { SetValue(SelectedItemsProperty, value); }
        }
        public static readonly DependencyProperty SelectedItemsProperty =
            DependencyProperty.Register("SelectedItems", typeof(ObservableCollection<object>), typeof(ListBox), null);

        /// <summary>
        /// The SelectionChangedCommand property.
        /// </summary>
        public ICommand SelectionChangedCommand {
            get { return (ICommand)GetValue(SelectionChangedCommandProperty); }
            set { SetValue(SelectionChangedCommandProperty, value); }
        }
        public static readonly DependencyProperty SelectionChangedCommandProperty =
            DependencyProperty.Register("SelectionChangedCommand", typeof(ICommand), typeof(ListBox), null);

        /// <summary>
        /// The SelectedListBoxItem property.
        /// </summary>
        public ListBoxItem SelectedListBoxItem {
            get { return (ListBoxItem)GetValue(SelectedListBoxItemProperty); }
            set { SetValue(SelectedListBoxItemProperty, value); }
        }
        public static readonly DependencyProperty SelectedListBoxItemProperty =
            DependencyProperty.Register("SelectedListBoxItem", typeof(ListBoxItem), typeof(ListBox), null);
        #endregion Selection


        /// <summary>
        /// ctor
        /// </summary>
        static ListBox() {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ListBox), new FrameworkPropertyMetadata(typeof(ListBox)));
        }

        protected override void PrepareContainerForItemOverride(DependencyObject element, object item) {
            base.PrepareContainerForItemOverride(element, item);
        }

        protected override DependencyObject GetContainerForItemOverride() {
            var listBoxItem = new ListBoxItem();
            listBoxItem.CustomItemTemplate = this.CustomItemTemplate;
            listBoxItem.SelectedItemTemplate = this.SelectedItemTemplate;
            listBoxItem.HoverItemTemplate = this.HoverItemTemplate;
            listBoxItem.HoverSelectedItemTemplate = this.HoverSelectedItemTemplate;
            listBoxItem.ListBox = this;
            return listBoxItem;
        }
    }
}
